#include "SPIPacket.h"
#include "File.h"

static void pabort(const char *s)
{
	if (errno != 0)
		perror(s);
	else
		printf("%s\n",s);
	abort();
}


int SPISet(const char* spi_device)
{
    int SPI_fd;

	/* 打开SPI设备 */
	SPI_fd = open(spi_device, O_RDWR);
	if (SPI_fd < 0)
	{
		printf("can't open device");
        exit(EXIT_FAILURE);
	}
	//set spi mode
	mode |= SPI_CPHA;
	if(ioctl(SPI_fd,SPI_IOC_WR_MODE32,&mode) == -1)
    {
        pabort("can't set spi mode");
        exit(EXIT_FAILURE);
    }

    return SPI_fd;
}

//计算文件总包数
unsigned int OTATotalPacketNum(unsigned int fileLength)
{
    unsigned int TOTAL_PACKET = (fileLength / PACKET_MAX_SZIE);
    return (((fileLength % PACKET_MAX_SZIE) == 0)? TOTAL_PACKET : ++TOTAL_PACKET);
}


/***
* 读取BIN文件，并填充单帧数据.e.g. 单帧数据和单帧有效数据大小
*@input: BinFileInfo 待升级文件信息
*@input: index 当前待填充的SPI帧序号
*@output: OTA_SinglePacketInfo_t 待填充后SPI帧的关键信息数据
*/
void BinFileConvertToSP(const BinFileInfo BinFile,FrameInfo_t index, OTA_SinglePacketInfo_t* o_SP)
{
    //TODO: 填充SPI帧数据
    unsigned int offset = index.CurrentPacket * PACKET_MAX_SZIE;
    o_SP->CurrentBasePacket = index.CurrentPacket;
    o_SP->TotalPacket = index.TotalPacket;
    o_SP->slot = BinFile.slot;

    if(index.CurrentPacket != index.TotalPacket)
    {
        o_SP->PacketValidSizeLength = PACKET_MAX_SZIE;
        memcpy(o_SP->PacketData,BinFile.fileBuffer + offset, PACKET_MAX_SZIE);
    }
    else//last packet
    {
        o_SP->PacketValidSizeLength = (BinFile.fileLength % PACKET_MAX_SZIE);
        memcpy(o_SP->PacketData,BinFile.fileBuffer + offset, (BinFile.fileLength%PACKET_MAX_SZIE));
    }
#if 0
    printf("Current packet is %d \r\n", index.CurrentPacket);
    //display the part of the file's data.
    for(int i=0;i<4;i++){
        for(int j=0;j<16;j++){
            printf("[%2x]:%02x ",j+i*16,o_SP->PacketData[j+i*16]);
        }
        printf("\r\n");
    }
#endif 
}

/***
* 填充单个SPI帧数据
*@input: OTA_SinglePacketInfo_t 待填充的SPI帧数据
*@output: OTASPIMsg_t spi_frame_TX 填充后的SPI帧数据
*/
void FillSingleFrame(const OTA_SinglePacketInfo_t* i_SP, OTASPIMsg_t* spi_frame)
{
    //TODO: 填充SPI帧数据
    spi_frame->tag[0] = i_SP->TotalPacket;
    spi_frame->tag[1] = i_SP->CurrentBasePacket;
    spi_frame->res1 = i_SP->PacketValidSizeLength;

    //fill the slot information
    if((*i_SP->slot == 'A') || (*i_SP->slot == 'a'))
        spi_frame->msgtype |= SPI_MSGTYPE_BINA;
    else if((*i_SP->slot == 'B') || (*i_SP->slot == 'b'))
        spi_frame->msgtype |= SPI_MSGTYPE_BINB;
    else{
        fprintf(stderr,"Invalid slot!,It should be 'A/a' or 'B/b',but received %c !\r\n",*i_SP->slot);
        exit(EXIT_FAILURE);
    }
    memcpy(spi_frame->data8,i_SP->PacketData,i_SP->PacketValidSizeLength);
}

